<!doctype html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AI流式聊天测试</title>
    <style>
      body {
        font-family:
          -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        max-width: 800px;
        margin: 0 auto;
        padding: 20px;
        background-color: #f5f5f5;
      }
      .container {
        background: white;
        border-radius: 10px;
        padding: 20px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }
      .input-group {
        margin-bottom: 20px;
      }
      label {
        display: block;
        margin-bottom: 5px;
        font-weight: bold;
      }
      input,
      textarea {
        width: 100%;
        padding: 10px;
        border: 1px solid #ddd;
        border-radius: 5px;
        font-size: 14px;
      }
      textarea {
        height: 100px;
        resize: vertical;
      }
      button {
        background: #007bff;
        color: white;
        border: none;
        padding: 10px 20px;
        border-radius: 5px;
        cursor: pointer;
        font-size: 16px;
        margin-right: 10px;
        margin-bottom: 10px;
      }
      button:hover {
        background: #0056b3;
      }
      button:disabled {
        background: #ccc;
        cursor: not-allowed;
      }
      .stop-btn {
        background: #dc3545;
      }
      .stop-btn:hover {
        background: #c82333;
      }
      .button-group {
        margin-bottom: 20px;
      }
      .response {
        margin-top: 20px;
        padding: 15px;
        background: #f8f9fa;
        border-radius: 5px;
        min-height: 100px;
        white-space: pre-wrap;
        border-left: 4px solid #007bff;
      }
      .loading {
        color: #666;
        font-style: italic;
      }
      .error {
        color: #dc3545;
        background: #f8d7da;
        border-left-color: #dc3545;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>🤖 AI流式聊天测试</h1>

      <div class="input-group">
        <label for="message">消息内容：</label>
        <textarea id="message" placeholder="请输入你的问题...">
你好，请介绍一下自己</textarea
        >
      </div>

      <div class="input-group">
        <label for="systemPrompt">系统提示词（可选）：</label>
        <input
          type="text"
          id="systemPrompt"
          placeholder="你是一个专业的编程助手"
          value="你是一个专业的编程助手"
        />
      </div>

      <div class="button-group">
        <button onclick="testEventSourceSSE()">开始聊天</button>
        <button id="stopBtn" class="stop-btn" onclick="stopStream()" disabled>
          停止生成
        </button>
      </div>

      <div id="response" class="response">等待响应...</div>
    </div>

    <script>
      const responseDiv = document.getElementById('response');
      const stopBtn = document.getElementById('stopBtn');
      let currentController = null; // 用于控制停止

      function getRequestBody() {
        return {
          message: document.getElementById('message').value,
          systemPrompt: document.getElementById('systemPrompt').value,
        };
      }

      function setLoading(loading) {
        const buttons = document.querySelectorAll('button:not(#stopBtn)');
        buttons.forEach((btn) => (btn.disabled = loading));
        stopBtn.disabled = !loading;

        if (loading) {
          responseDiv.className = 'response loading';
          responseDiv.textContent = '正在处理中...';
        }
      }

      function stopStream() {
        if (currentController) {
          currentController.abort();
          currentController = null;
          setLoading(false);
          responseDiv.className = 'response';
          responseDiv.textContent += '\n\n[已停止生成]';
        }
      }

      // 使用原生fetch实现SSE，支持停止功能
      async function testEventSourceSSE() {
        setLoading(true);
        responseDiv.className = 'response';
        responseDiv.textContent = '';

        // 创建AbortController用于停止
        currentController = new AbortController();
        const requestUrl = 'http://localhost:3000/ai/chat/stream-sse';
        try {
          const response = await fetch(requestUrl, {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify(getRequestBody()),
            signal: currentController.signal,
          });

          if (!response.ok) {
            throw new Error(`HTTP错误: ${response.status}`);
          }

          console.log('SSE连接已建立');
          const reader = response.body.getReader();
          const decoder = new TextDecoder();

          while (true) {
            const { done, value } = await reader.read();

            if (done) {
              console.log('流读取完成');
              break;
            }

            const chunk = decoder.decode(value, { stream: true });
            const lines = chunk.split('\n');

            for (const line of lines) {
              if (line.startsWith('data: ') && line.length > 6) {
                try {
                  const data = JSON.parse(line.slice(6));

                  if (data.type === 'start') {
                    console.log('开始接收数据');
                    responseDiv.textContent = '';
                  } else if (data.type === 'chunk') {
                    responseDiv.textContent += data.content;
                  } else if (data.type === 'end') {
                    console.log('数据接收完成');
                    break;
                  } else if (data.type === 'error') {
                    responseDiv.className = 'response error';
                    responseDiv.textContent = `错误: ${data.message}`;
                    return;
                  }
                } catch (parseError) {
                  console.warn('解析SSE数据失败:', line, parseError);
                }
              }
            }
          }
        } catch (error) {
          if (error.name === 'AbortError') {
            console.log('用户主动停止了请求');
            responseDiv.textContent += '\n\n[用户停止生成]';
          } else {
            console.error('SSE错误:', error);
            responseDiv.className = 'response error';
            responseDiv.textContent = `连接错误: ${error.message}`;
          }
        } finally {
          setLoading(false);
          currentController = null;
        }
      }
    </script>
  </body>
</html>
